<template>
  <div class="files-upload">
    <el-table :data="fileTypeList" style="width: 100%">
      <el-table-column prop="file_type" label="文件类型" width="180">
        <template #default="scope">
          <div class="file-type-cell">
            {{ scope.row.file_type }}
            <span v-if="scope.row.remark" class="required-mark">{{scope.row.remark}}</span>
            <span v-if="scope.row.required" class="required-mark">*</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="文件列表">
        <template #default="scope">
          <div class="uploaded-files">
            <template v-if="getUploadedFiles(scope.row.file_type).length > 0">
              <div v-for="file in getUploadedFiles(scope.row.file_type)" 
                   :key="file.doc_id" 
                   class="file-item">
                <span class="file-name">{{ file.file_name }}</span>
                <span class="file-size">({{ formatFileSize(file.file_size_kb) }})</span>
                <el-icon
                v-if="!readOnly"
                  class="delete-icon" 
                  @click="deleteFile(file)"
                >
                  <Close />
                </el-icon>
                <div>
                <span v-if="readOnly">
                  <el-button 
                    v-if="isPreviewable(file)"
                    type="primary" 
                    size="small" 
                    plain 
                    @click="previewFile(file)">
                    预览
                  </el-button>
                  <el-button 
                    type="primary" 
                    size="small" 
                    plain
                    @click="downloadFile(file)">
                    下载
                  </el-button>
                </span>
              </div>
              </div>
            </template>
            <div v-else class="no-files">
              <span class="required-text">
                {{ scope.row.required ? '*必须上传文件' : '文件未上传' }}
              </span>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column v-if="!readOnly" label="操作" width="120">
        <template #default="scope">
          <el-upload
            class="upload-demo"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="(uploadFile) => handleFileSelect(uploadFile, scope.row.file_type, scope.row.format, scope.row.sizeLimit)"
            :multiple="true"
            :on-exceed="(files) => handleExceed(files, scope.row)"
            :limit="getFileLimit(scope.row)"
            accept=".doc,.docx,.ppt,.pptx,.xls,.xlsx,.txt,.pdf,.jpg,.jpeg,.png,.zip,.rar,.7z"
          >
            <el-tooltip placement="right" max-width="300">
              <template #content>
                <div>
                  <div>支持上传以下格式：</div>
                  <div>• 文档类：doc/docx、ppt/pptx、xls/xlsx、txt、pdf</div>
                  <div>• 图片类：jpg/jpeg、png</div>
                  <div>• 压缩包：zip、rar、7z</div>
                  <div class="text-xs mt-1">单个文件大小不超过 100 MB</div>
                </div>
              </template>
              <el-button size="small" type="primary">上传文件</el-button>
            </el-tooltip>
          </el-upload>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      :title="filePreviewName"
      v-model="isPreviewOpen"
      :style="{ height: '100vh', margin: '0 auto', padding: 0 }"
      width="70%"
    >
      <iframe v-if="pdfUrl" :src="pdfUrl" style="width: 100%; height: 85vh"></iframe>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';
import { Close } from '@element-plus/icons-vue';
import * as KmsApi from '@/api/project/kms';
import { staticData } from '@/views/project/mixins/staticDataMixin'

const props = defineProps({
  fileTypes: {
    type: Array,
    required: true
  },
  projectInfo: {
    type: Object,
    required: true
  },
  readOnly: {
    type: Boolean,
    default: false
  }
});

const {previewableTypes} = staticData()
const isPreviewOpen = ref(false);
const pdfUrl = ref('');
const filePreviewName = ref('');

const fileTypeList = ref(props.fileTypes);
const defaultLimit = 10;
// 获取指定文件类型的已上传文件
const getUploadedFiles = (fileType) => {
  return props.projectInfo.files?.filter(file => file.file_type === fileType) || [];
};

// 验证必需文件是否已上传
const validateFiles = () => {
  const requiredFiles = props.fileTypes.filter(file => file.required);
  const missingFiles = [];
  
  for (const requiredFile of requiredFiles) {
    const uploadedFiles = getUploadedFiles(requiredFile.file_type);
    
    if (uploadedFiles.length === 0) {
      missingFiles.push(requiredFile.file_type);
    }
  }
  
  if (missingFiles.length > 0) {
    ElMessage.error(`请上传以下必需文件：${missingFiles.join('、')}`);
    return false;
  }
  
  return true;
};

// 格式化文件大小
const formatFileSize = (sizeInKB) => {
  if (sizeInKB < 1024) {
    return `${sizeInKB}KB`;
  } else {
    return `${(sizeInKB / 1024).toFixed(2)}MB`;
  }
};

// 获取文件上传限制，处理 file_limit 可能不存在的情况
const getFileLimit = (row) => {
  return row?.file_limit ?? defaultLimit;
};

// 提示处理超出文件数量限制
const handleExceed = (files, row) => {
  const actualLimit = row?.file_limit ?? defaultLimit;
  ElMessage.warning(
    `当前限制选择 ${actualLimit} 个文件，本次选择了 ${files.length} 个文件`
  );
};

// 状态变量
const isUploading = ref(false);
const uploadQueue = ref([]);
const uploadCount = ref(0);
const uploadSuccessCount = ref(0);
const uploadFailCount = ref(0);

// 处理文件选择 - 收集所有文件后批量上传
const handleFileSelect = async (file, fileType, fileFormat, sizeLimit) => {
  if (!file) return;
  
  // 定义允许的文件类型
  const defaultFileTypes = [
    'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'txt', 'pdf',
    'jpg', 'jpeg', 'png', 'zip', 'rar', '7z'
  ];
  const allowedFileTypes = fileFormat || defaultFileTypes;

  // 获取文件扩展名
  const extension = file.name.split('.').pop().toLowerCase();
  
  // 验证文件类型
  if (!allowedFileTypes.includes(extension)) {
    ElMessage.error('不支持的文件格式，请上传正确格式的文件');
    return;
  }

  if (sizeLimit) {
    const isSizeLimit = file.size / 1024 <  sizeLimit;
    if (!isSizeLimit) {
      ElMessage.error(`文件大小不能超过 ${sizeLimit} KB!`);
      return;
    }
  }
  
  const isLt100M = file.size / 1024 / 1024 < 100;
  
  if (!isLt100M) {
    ElMessage.error('文件大小不能超过 100 MB!');
    return;
  }
  
  // 将验证通过的文件添加到上传队列
  uploadQueue.value.push({
    file: file.raw,
    fileType: fileType,
    fileName: file.name
  });
  
  // 如果当前不在上传状态，则开始批量上传
  if (!isUploading.value && uploadQueue.value.length > 0) {
    await batchUploadFiles();
  }
};

// 批量处理文件上传
const batchUploadFiles = async () => {
  if (uploadQueue.value.length === 0) return;

  isUploading.value = true;
  const currentBatch = [...uploadQueue.value];
  uploadCount.value += currentBatch.length
  uploadQueue.value = []; // 清空队列，避免重复上传
  
  // 显示上传中提示
  const loadingInstance = ElLoading.service({
    // text: `正在上传 ${currentBatch.length} 个文件...`,
    text: `正在上传 ${uploadCount.value} 个文件...`,
    background: 'rgba(0, 0, 0, 0.7)'
  });
  
  try {
    // 并发上传所有文件
    const uploadPromises = currentBatch.map(item => 
      uploadFile(item.file, item.fileType, item.fileName, false) // 传入false表示不显示单个文件上传成功提示
    );
    
    const results = await Promise.all(uploadPromises);
    
    // 关闭加载提示
    loadingInstance.close();
    
    // 计算成功和失败的文件数
    const successCount = results.filter(r => r === true).length;
    uploadSuccessCount.value += successCount;
    const failCount = results.filter(r => r === false).length;
    uploadFailCount.value += failCount;
    // 显示上传完成的提示
    if (uploadFailCount.value === 0) {
      // ElMessage.success(`${successCount} 个文件上传成功`);
      ElMessage.success({
        // text: `正在上传 ${currentBatch.length} 个文件...`,
        message: `${uploadSuccessCount.value} 个文件上传成功`,
        duration: 1000,
      });
    } else if (uploadSuccessCount.value === 0) {
      ElMessage.error(`所有文件上传失败`);
    } else {
      ElMessage.warning(`${uploadSuccessCount.value} 个文件上传成功，${uploadFailCount.value} 个文件上传失败`);
    }
  } catch (error) {
    console.error('批量上传文件出错', error);
    ElMessage.error('上传过程中发生错误');
    loadingInstance.close();
  } finally {
    isUploading.value = false;
    // 触发事件通知父组件刷新文件列表
    emit('getProjectFilesInfo');

    // 处理剩余的上传队列
    if (uploadQueue.value.length > 0) {
      await batchUploadFiles();
    }


  }
};

// 上传单个文件 - 支持静默上传
const uploadFile = async (fileRaw, fileType, fileName, showMessage = true) => {
  try {
    const uploadData = new FormData();
    uploadData.append('resource_name', props.projectInfo.project_name || '');
    uploadData.append('resource_id', props.projectInfo.project_code || '');
    uploadData.append('file_type', fileType);
    uploadData.append('file', fileRaw);
    
    const response = await KmsApi.uploadFile(uploadData);
    
    // 只有在showMessage为true时才显示单个文件上传成功的消息
    if (showMessage) {
      ElMessage.success(`文件上传成功`);
      // 单独上传也需要触发事件通知父组件刷新文件列表
      
    }
    emit('getProjectFilesInfo');
    return true;
  } catch (error) {
    console.error('文件上传失败', error);
    if (showMessage) {
      ElMessage.error(`文件上传失败`);
    }
    return false;
  }
};

// 删除文件
const deleteFile = async (file) => {
  try {
    // 调用删除文件的 API
    const params = {
      file_id: file.doc_id,
    }
    await KmsApi.deleteFile(params);
    // await new Promise((resolve) => setTimeout(resolve, 1100));
    ElMessage.success('文件删除成功');
    // 触发事件通知父组件刷新文件列表
    emit('getProjectFilesInfo');
  } catch (error) {
    console.error('文件删除失败', error);
    ElMessage.error('文件删除失败');
  }
};

const isPreviewable = (file) => {
  return previewableTypes.includes(file.suffix);
};

// 预览附件
const previewFile = (file) => {
  const params = {
    doc_id: file.doc_id,
    is_preview: true
  }
  KmsApi.previewAndDownloadFile(params).then((res) => {
    filePreviewName.value = file.file_name
    const blobPDF = new Blob([res], { type: 'application/pdf' })
    pdfUrl.value = '/pdfjs/web/viewer.html?file=' + window.URL.createObjectURL(blobPDF)
    isPreviewOpen.value = true
  })
}

// 下载附件
const downloadFile = (file) => {
  const params = {
    doc_id: file.doc_id,
    is_preview: false
  }
  KmsApi.previewAndDownloadFile(params).then((res) => {
    const downloadFileName = file.file_name
    const blobData = new Blob([res])
    const fileUrl = URL.createObjectURL(blobData);
    const link = document.createElement('a');
    link.href = fileUrl;
    link.setAttribute('download', downloadFileName);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(fileUrl);
  })
}

// 定义组件事件
const emit = defineEmits(['getProjectFilesInfo']);

// 暴露验证方法给父组件
defineExpose({
  validateFiles
});
</script>

<style scoped>
.files-upload {
  margin-bottom: 20px;
}

.file-type-cell {
  display: flex;
  align-items: center;
  gap: 4px;
}

.required-mark {
  color: #f56c6c;
  font-size: smaller;
}

.uploaded-files {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.file-item {
  display: flex;
  align-items: center;
  padding: 4px 8px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.file-name {
  flex: 1;
  margin-right: 8px;
}

.file-size {
  color: #909399;
  font-size: 12px;
  margin-right: 8px;
}

.delete-icon {
  cursor: pointer;
  color: #909399;
  transition: color 0.2s;
}

.delete-icon:hover {
  color: #f56c6c;
}

.no-files {
  padding: 4px 0;
}

.required-text {
  color: #f56c6c;
  font-style: italic;
}

:deep(.el-upload) {
  width: 100%;
}

:deep(.el-upload .el-button) {
  width: 100%;
}

.file-actions {
  display: flex;
  gap: 4px;
  white-space: nowrap;
}
</style>